---
page_title: Stack configuration file reference
description: Stacks help you provision and coordinate your infrastructure lifecycle at scale. Learn how to write a Stack configurion file to create a Stack for your infrastructure.
---

# Stack configuration file reference

A Stack configuration file defines all the infrastructure pieces included in a Stack. Every Stack needs a configuration file, `tfstack.hcl`, and this page describes all the blocks you can use within a Stack configuration file. 

## `component` block configuration

The `component` block defines the infrastructure to include in your Stack. Each Stack requires at least one `component` block. Add a `component` block to your configuration for every module you want to include in your Stack.

The following list outlines field hierarchy, language-specific data types, and requirements in the `component` block.

### Complete configuration

When every field is defined, a `component` block has the following form:

```hcl
component "unique_name" {
    source = <The Terraform module to source>
    inputs = {
        input_name          = <variable_value>
    }
    providers = {
        random    = provider.provider_name.provider_alias
    }
}
```

### Specification

This section details the fields you can configure in the `component` block.

Each Stack must have at least one `component` block, and the label of the component block must be unique within your Stack. The `component` block is a map that defines a module to source, input variables for that module, and the names of the providers that your module requires.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `source` | The Terraform module to [source](https://developer.hashicorp.com/terraform/language/modules/sources) for this component. | string | Required |
| `version` | If you declare a module from the public Terraform registry in the source field, you can define which module version to use.  | string | Optional |
| `inputs` | A mapping of module input variable names to values. The keys of this map must correspond to the variable names defined by the `source` module. The values can be one of three types: A variable reference such as `var.variable_name`, a component output such as `component.component_name.output_name`, or a literal valid HCL value such as "string value".  | map | Required |
| `providers` | A mapping of provider names to providers declared in your Stack configuration. Modules cannot configure their own providers. You must [declare providers](/terraform/language/stacks/create/declare-providers) in the top level of the Stack and pass them into each module in the Stack. | map | Required |
| `depends_on` | A list of other components that HCP Terraform must execute before this component. You do not need to include another component’s outputs in this list, because Terraform automatically recognizes them.  | list | Optional |

### Reference

The `component` block also supports the `for_each` meta-argument.  For example, the following configuration uses `for_each` to provision modules in multiple AWS regions for a given environment.

```hcl
component "s3" {
    for_each = var.regions

    source = "./s3"

    inputs = {
        region = each.value
    }

    providers = {
        aws    = provider.aws.configurations[each.value]
        random = provider.random.this
    }
}
```

To learn more about breaking down your infrastructure into components, refer to [Define Stack configuration](/terraform/language/stacks/create/config).

## `variable` block configuration 

Use the `variable` block to declare input variables for your Stack configuration. Using `variable` blocks in Stacks is similar to traditional Terraform configurations but with a few minor differences.

In Stack configurations, `variable` blocks must define a `type` field and do not support the `validation` argument. Learn more about Terraform [Variables](/terraform/language/values/variables).

### Complete configuration

When every field is defined, a `variable` block has the following form:
```hcl
variable "unique_variable_name" {
    description = "Description of the purpose of this variable"
    type        = string
    default     = "Default variable value"
    sensitive   = false
    nullable    = false
}
```

### Specification

This section provides details about the fields you can configure in the `variable` block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `type` | A type constraint for the variable's value. Can be string, number, bool, list, map, set, tuple, or object. Stacks require you to declare a `type` for your variables.  | string | Required |
| `description` | A human-friendly description for the variable. | string | Optional |
| `default` | A default value for the variable which Terraform uses if no value is provided. | any | Optional |
| `sensitive` | Marks the variable as sensitive, which prevents its value from being displayed in logs or in the HCP Terraform user interface. | bool | Optional |
| `nullable` | Specifies whether the variable can be null. | bool | Optional |
| `ephemeral` | Marks that this variable’s value is dynamic. For example, an expiring authentication token is `ephemeral`. Learn more about [Ephemeral variables](/terraform/language/values/variables#exclude-values-from-state). | bool | Optional |

## `output` block configuration

Use the `output` block to make information about your infrastructure available in the HCP Terraform UI to expose information about your Stack. The `output` block functions the same way in Stack configuration as it does in traditional Terraform configurations with a few small differences. 

In Stack configurations, `output` blocks require the `type` argument, and they do not support the `preconditions` block. Learn more about [Outputs](/terraform/language/values/outputs).

### Complete configuration

When every field is defined, an `output` block has the following form:
```hcl
output "unique_name_of_output" {
  description = "Description of the purpose of this output"
  type        = string
  value       = component.component_name.some_value
  sensitive   = false
  ephemeral   = false
}
```

### Specification

This section provides details about the fields you can configure in the `output` block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `description` | A human-friendly description for the output. | string | Optional |
| `type` | The type of the output. | type constraint | Required |
| `value` | The value to output. | any | Required |
| `sensitive` | Marks the variable as sensitive, which prevents its value from being displayed in logs or in the HCP Terraform UI.  | bool | Optional |
| `ephemeral` | Whether to exclude the value from plans and state data. | bool | Optional |

## `required_providers` and `provider` block configuration

Terraform relies on plugins called providers to interact with cloud providers, SaaS providers, and other APIs. 

The `required_providers` block works exactly as it does in traditional Terraform configurations. Learn more about [the `required_providers` block](/terraform/language/providers/requirements). The `provider` block functions mostly the same way in Stack configuration as it does in traditional Terraform configurations, with a few differences. 

The `provider` block differs in Stack configurations in the following ways:

* Supports the `for_each` [meta-argument](/terraform/language/meta-arguments/for_each)  
* Defines aliases in the `provider` block header rather than as an argument  
* Accepts arguments using a config block

You must also define your providers at the top level of your Stack configuration in a `tfstack.hcl` file. You cannot define providers within the modules your component blocks source.

### Complete configuration

Provider configuration differs depending on which API you are interacting with. Below, you can configure the AWS provider and pass it to your S3 component.

```hcl
required_providers {
    aws = {
        source  = "hashicorp/aws"
        version = "~> 5.7.0"
    }
}

# "main" is the alias for this provider
provider "aws" "main" {
# The config block accepts the configuration for a provider
    config {
        region = var.region

        assume_role_with_web_identity {
            role_arn           = var.role_arn
            web_identity_token = var.identity_token
        }
    }
}
```

The `provider` block also supports the `for_each` meta-argument. For example, the following provider uses `for_each` to create multiple AWS configurations.

```hcl
provider "aws" "configurations" {
    for_each = var.regions

    config {
        region = each.value

        assume_role_with_web_identity {
            role_arn           = var.role_arn
            web_identity_token = var.identity_token
        }

        default_tags {
            tags = var.default_tags
        }
    }
}
```

For more information on declaring providers in Stacks, refer to [Declare providers](/terraform/language/stacks/create/declare-providers).

## `locals` block configuration

A local value assigns a name to an expression, so you can use the name multiple times within your Stack configuration instead of repeating the expression. The `locals` block works exactly as it does in traditional Terraform configurations. Learn more about [the `locals` block](/terraform/language/values/locals).


## `removed` block configuration

Stacks take a systematic approach to removing components. To remove a component from a Stack, you must use the `removed` block to ensure HCP Terraform knows which components to remove and which providers it requires to remove that component. 

Do not remove providers from your stack configuration without first removing the components that require those providers. HCP Terraform requires a component's providers to ensure it can successfully remove that component. 


### Complete configuration

When every field is defined, a `removed` block has the following form:

```hcl

removed {
    source = "<The module that the component you want to remove uses>"

    from = component.component_name
    providers = {
        aws = provider.aws.this
    }
}
```


### Specification

This section provides details about the fields you can configure in the `removed` block.

| Field | Description | Type | Required |
| :---- | :---- | :---- | :---- |
| `from` | The name of the resource you want to remove. | string | Required |
| `source` | The source module of the component you want to remove. | string | Required |
| `providers` | A mapping of provider names to the providers that the component you want to remove uses. HCP Terraform needs your component providers to remove that component properly. | map | Required |

### Reference

The `removed` block also supports the `for_each` meta-argument to support removing multiple `components`.  For example, if you are trying to remove a dynamic component that HCP Terraform deploys in multiple AWS regions.

```hcl
component "s3_buckets" {
    source = "./s3"

    for_each = var.regions

    providers = {
        aws = provider.aws.config[each.value]
    }

    variables = {
        region = each.value
    }
}
```

You can use the `for_each` meta-argument to remove each component dynamically.

```hcl
removed {
    source = "./s3"

    for_each = var.regions

    from = component.s3_buckets[each.value]
    providers = {
        aws = provider.aws.config[each.value]
    }
}
```

HCP Terraform iterates through the `var.regions` variable and removes each AWS region's corresponding component. Expanding on this example, you could add a new variable to keep track of the regions you want to remove.

```hcl
variable "regions" {
    type = set(string)
}

# Adding a region to this variable instructs HCP Terraform to remove it.
variable "removed_regions" {
    type = set(string)
}

component "s3_buckets" {
    source = "./s3"

    for_each = var.regions

    providers = {
        aws = provider.aws.config[each.value]
    }

    variables = {
        region = each.value
    }
}

removed {
    source = "./s3"
    # Iterate and remove the regions in our new removed_regions variable.
    for_each = var.removed_regions

    from = component.s3_buckets[each.value]
    providers = {
        aws = provider.aws.config[each.value]
    }
}
```

When you move a region from `regions` to the `removed_regions` variable, HCP Terraform plans to remove that region's corresponding components.
